#include "bsp_tapeLight.h"

#include "bsp_key.h"
#include "bsp_led.h"

#include <stdio.h>

#include "lz_hardware.h"

#include "los_task.h"


#define TAPELIGHT_PWM_FREQ                    (200)     // 100Hz 以上 人眼感知不到闪烁

typedef enum
{
    GPIO_MODE,
    PWM_MODE
}light_mode_t;

struct TapeLight
{
    int id;
    //GPIO
    int gpio_pin;
    unsigned int pwm_port;
    light_mode_t cur_mode;  // 0:GPIO_MODE  1:PWM_MODE

    int light_value;      // 0 ~ 100      
    int pre_value;
};

tapeLight_t light_masterBedroom = {
    .id = 0,
    .gpio_pin = GPIO0_PB4,
    .pwm_port = 0,
    .cur_mode = GPIO_MODE,
    .light_value = 0,
    .pre_value = 0
},
light_livingRoom = {
    .id = 1,
    .gpio_pin = GPIO0_PB5,
    .pwm_port = 1,
    .cur_mode = GPIO_MODE,
    .light_value = 0,
    .pre_value = 0
},
light_kitchen = {
    .id = 2,
    .gpio_pin = GPIO0_PC0,
    .pwm_port = 3,
    .cur_mode = GPIO_MODE,
    .light_value = 0,
    .pre_value = 0
};


static int tapeLight_gpio_init(tapeLight_t *self);
static int tapeLight_pwm_init(tapeLight_t *self);

int tapeLight_init_all(void)
{
    int ret = 0;

    ret = tapeLight_gpio_init(&light_masterBedroom);
    if(ret != 0)
    {
        // printf("[tapeLight_init_all] ");
        return -1;
    }

    ret = tapeLight_gpio_init(&light_livingRoom);
    if(ret != 0)
    {
        return -2;
    }

    ret = tapeLight_gpio_init(&light_kitchen);
    if(ret != 0)
    {
        return -3;
    }

    return 0;
}

int tapeLight_set_lightValue(tapeLight_t *self, int lightValue)
{
    if(NULL == self)
        return -1;

    //限制范围
    if(lightValue < 0) lightValue = 0;
    else if(lightValue > 100) lightValue = 100;

    self->pre_value = self->light_value;
    self->light_value = lightValue;

    printf("[tapeLight_set_lightValue] light_value:%d.\n", self->light_value);

    if(0 == self->light_value)
    {
        if(PWM_MODE == self->cur_mode)
        {
            //关闭PWM
            // tapeLight_pwm_deinit(self);
            // IoTPwmStop(self->pwm_port);

            tapeLight_gpio_init(self);

            self->cur_mode = GPIO_MODE;
        }

        LzGpioSetVal(self->gpio_pin, LZGPIO_LEVEL_LOW);
    }
    else if(100 == self->light_value)
    {
        if(PWM_MODE == self->cur_mode)
        {
            //关闭PWM
            // tapeLight_pwm_deinit(self);
            // IoTPwmStop(self->pwm_port);

            tapeLight_gpio_init(self);

            self->cur_mode = GPIO_MODE;
        }

        LzGpioSetVal(self->gpio_pin, LZGPIO_LEVEL_HIGH);
    }
    else if(self->light_value > 0 && self->light_value < 100)    // 1 ~ 99
    {
        if(GPIO_MODE == self->cur_mode)
        {
            //GPIO置低
            LzGpioSetVal(self->gpio_pin, LZGPIO_LEVEL_LOW);
            // tapeLight_gpio_deinit(self);

            self->cur_mode = PWM_MODE;
        }

        tapeLight_pwm_init(self);
        IoTPwmStart(self->pwm_port, self->light_value, TAPELIGHT_PWM_FREQ);
    }

    return 0;
}


static int tapeLight_gpio_init(tapeLight_t *self)
{
    unsigned int ret = 0;

    if(NULL == self)
        return -1;  //参数为空

    ret = LzGpioInit(self->gpio_pin);
    // if(ret != 0)
    // {
    //     printf("[tapeLight_gpio_init] LzGpioInit id: %d error, ret: 0x%x\n", self->id, ret);
    //     return -2;
    // }

    ret = PinctrlSet(self->gpio_pin, MUX_FUNC0, PULL_DOWN, DRIVE_LEVEL2);//引脚复用配置GPIO， MUX_FUNC0 GPIO模式，DRIE_LEVEL0 2mA最低驱动能力 Level3 12mA
    // if(ret != 0)
    // {
    //     printf("[tapeLight_gpio_init] PinctrlSet id: %d error, ret: 0x%x\n", self->id, ret);
    //     return -3;
    // }

    ret = LzGpioSetDir(self->gpio_pin, LZGPIO_DIR_OUT);    //设置输出
    // if(ret != 0)
    // {
    //     printf("[tapeLight_gpio_init] LzGpioSetDir id: %d error, ret: 0x%x\n", self->id, ret);
    //     return -4;
    // }

    LzGpioSetVal(self->gpio_pin, LZGPIO_LEVEL_LOW);

    return 0;
}

// static int tapeLight_gpio_deinit(tapeLight_t *self)
// {
//     unsigned int ret = 0;

//     if(NULL == self)
//         return -1;

//     ret = LzGpioDeinit(self->gpio_pin);
//     if(ret != 0)
//     {
//         printf("[tapeLight_gpio_deinit] LzGpioDeinit error, ret:0x%x\n", ret);
//         return -2;
//     }

//     return 0;
// }

static int tapeLight_pwm_init(tapeLight_t *self)
{
    unsigned int ret = 0;

    if(NULL == self)
        return -1;

    ret = IoTPwmInit(self->pwm_port);
    if(ret != 0)
    {
        printf("[tapeLight_pwm_init] IoTPwmInit error, ret:0x%x", ret);
        return -2;
    }

    return 0;
}

// static int tapeLight_pwm_deinit(tapeLight_t *self)
// {
//     unsigned int ret = 0;

//     if(NULL == self)
//         return -1;

//     ret = IoTPwmStop(self->pwm_port);
//     // if(ret != 0)
//     // {
//     //     printf("[tapeLight_pwm_deinit] IoTPwmStop error, ret: 0x%x\n", ret);
//     //     return -2;
//     // }

//     ret = IoTPwmDeinit(self->pwm_port);
//     if(ret != 0)
//     {
//         printf("[tapeLight_pwm_deinit] IoTPwmDeinit error, ret: 0x%x\n", ret);
//         return -3;
//     }

//     return 0;
// }

void tapeLight_test(void)
{
    int light_value = 100;
    int cnt = 0;
    tapeLight_t *pLight = &light_masterBedroom;
    while(1)
    {
        KEY_TYPE key = 0;

        key = key_scan(0);
        switch(key)
        {
        case KEY1_PRES:
            pLight = &light_masterBedroom;
            break;
        case KEY2_PRES:
            pLight = &light_livingRoom;
            break;
        case KEY3_PRES:
            pLight = &light_kitchen;
            break;
        default:
            break;
        }
        
        if(cnt > 5) // 5 * 100ms == 500ms
        {
            cnt = 0;
            
            light_value ++;
            if(light_value > 100)
                light_value = 0;

            printf("[bsp init] light_value: %d\n", light_value);
            tapeLight_set_lightValue(pLight, light_value);

            led_toggle(LED1);
        }

        LOS_Msleep(100);
        cnt ++;
    }
}

